import React, { useState, memo, useMemo } from 'react'

type ChildProps = {
  click: () => void
}

type Child2Props = {
  user: { age: number }
}

const Child1 = memo(({ click }: ChildProps) => {
  console.log('Child1 组件更新')
  return (
    <div style={{ backgroundColor: 'lightsalmon', padding: 5 }}>
      子组件1：<button onClick={click}>点击</button>
    </div>
  )
})

const Child2 = React.memo(({ user }: Child2Props) => {
  console.log('Child2 组件更新')
  return (
    <div style={{ backgroundColor: 'lightgoldenrodyellow', padding: 5 }}>子组件2 -- {user.age}</div>
  )
})

const App = () => {
  const [count, setCount] = useState(0)
  const [theme, setTheme] = useState('lightseagreen')

  // const handleClick = useCallback(() => {
  //   console.log('依赖 count 数据')
  //   setCount(count + 10)
  // }, [count])

  // useMemo Hook 可以记忆任意数据，可以用来模拟 useCallback
  // useCallback 的第一个参数，是需要记忆的函数
  // useMemo 第一个参数的返回值，才是要记忆的数据，例如下面的回调函数
  // 注意：
  //  1. useCallback 第一个参数就是要记忆的函数，该函数不会立即执行，只有调用时才会执行
  //  2. useMemo 第一个参数才是要记忆的函数，所以为了拿到返回值，第一个参数会立即执行
  const handleClick = useMemo(() => {
    console.log('依赖 count 数据')
    return () => {
      setCount(count + 10)
    }
  }, [count])

  const user = useMemo(() => {
    console.log('useMemo 回调会被立即执行')
    return { age: 1 + count }
  }, [count])

  return (
    <div style={{ backgroundColor: theme, padding: 10 }}>
      <button
        onClick={() => setTheme(theme === 'lightseagreen' ? 'lightskyblue' : 'lightseagreen')}
      >
        切换主题
      </button>

      <h1>计数器：{count}</h1>
      <button onClick={() => setCount(count + 1)}>+1</button>

      <hr />

      {/* 子组件 */}
      <Child1 click={handleClick} />

      <hr />

      <Child2 user={user} />
    </div>
  )
}

export default App
